////////////////////////////////////////////////////////////////////
// Programme d'extraction/réinsertion de textes pour Chrono Cross
////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////
// Nemesis pour Terminus Traduction (tt_nemesis@yahoo.fr)
// Date de création :		24/08/03
// Dernière modification :	04/09/03
////////////////////////////////////////////////////////////////////

// Entete
#include "Textes.h"

// Type de pointeurs (16 ou 32 bits)
int Txt_Type_Ptr;

/*------------------------------------------------------------------
  Initialisation des infos sur les textes d'un fichier
--------------------------------------------------------------------
 <- dir : chemin partiel des infos à charger
 <- fich : fichier d'infos à charger
 <- inout = TBL_IN ou TBL_OUT déterminant le dossier de la table
------------------------------------------------------------------*/
void Txt_Infos (char *dir, char *fich, int inout)
{
	// Fichier des infos
	FILE *infos_f;
	// Nom de l'iso (chemin)
	char infos_nom[TXT_NOM_MAX];
	// Ligne d'informations
	char ligne[TXT_LIGNE_MAX];
	// Table de caractères associée
	char table[TXT_FICHS_NOM];

	// Ouverture du fichier des infos principales
	sprintf(infos_nom,"%s%s%s%s.%s",
		DIR_INFOS,DIR_INFOS_TXT,dir,fich,EXT_INFOS);
	infos_f=fopen(infos_nom,"rb");

	if (infos_f==NULL)
		Main_Message_S("Erreur d'ouverture des infos.\n","",ER);
	else {
		// Parcours du fichier
		while (fgets(ligne,TXT_LIGNE_MAX,infos_f)!=NULL)
			// Cas d'un commentaire ou d'un blanc
			if (ligne[0]!=COMMENT) {
				sscanf(ligne,"%d - %s",&Txt_Type_Ptr,table);
				// Chargement de la table de caractères
				Tbl_Libere();
				Tbl_Charge(table, inout);
			}
		// Fermeture du fichier des infos
		fclose(infos_f);
	}
}

/*------------------------------------------------------------------
  Inscription d'un pointeur dans le texte de sortie
--------------------------------------------------------------------
 <- num : numéro de pointeur à écrire
 <- out_f : fichier où l'on écrit les informations
------------------------------------------------------------------*/
void Txt_Pointeur (int num,FILE *out_f)
{
	int c;

	fputc('\n',out_f);
	for(c=0;c<TXT_PTR_LARG-6;c++)
		fputc(TXT_PTR_CAR,out_f);
	fprintf(out_f,TXT_PTR_NUM,num);
}

/*------------------------------------------------------------------
  Extraction des textes d'un fichier
--------------------------------------------------------------------
 <- fich : dossier|fichier de textes (sans extension pour dossier)
------------------------------------------------------------------*/
void Txt_Extraction (char *fich)
{
	// Dossier/fichiers
	char* dir;
	char* fichier;
	// Fichier de textes à décompresser
	FILE *txt_f;
	char txt_nom[TXT_NOM_MAX];
	char *txt_nom2;
	char txt_nom_complet[TXT_NOM_MAX];
	// Fichier de sortie
	FILE *out_f;
	// Nom du dossier
	char dossier[TXT_NOM_MAX];
	// Pointeurs sur le texte
	unsigned _int16 adresse16;
	unsigned _int32 adresse;
	int adresses_nb=-1;
	// Index des fichiers et blocs
	int t;

	Main_Message_S("Extraction des textes de %s... ",fich,OK);

	// Décomposition dossier/fichier
	dir=strtok(fich,SEPARATEUR);
	if (dir[0]==NEUTRE)
		dir[0]=0;
	fichier=strtok(NULL,SEPARATEUR);

	// Recherche du fichier de textes
	sprintf(txt_nom,"%04d",atoi(fichier));
	sprintf(dossier,"%s%s",DIR_FICH_IN,dir);
	Fichier_Cherche(dossier,txt_nom,EXT_TBT,&txt_nom2);
	sprintf(txt_nom_complet,"%s%s",dossier,txt_nom2);
	// Ouverture du fichier de textes
	txt_f=fopen(txt_nom_complet,"rb");

	// Fichier existant ?
	if (txt_f==NULL)
		Main_Message_S("Impossible d'ouvrir le fichier.\n","",ER);
	else {
		// Chargement des infos sur les textes
		Txt_Infos(dir,txt_nom,TBL_IN);
		// Ouverture du texte extrait
		strcpy(&txt_nom_complet[strlen(txt_nom_complet)-3],EXT_TXT);
		out_f=fopen(txt_nom_complet,"w");
		// Chargement de l'adresse de base (16 ou 32 bits)
		if (Txt_Type_Ptr==2) {
			fread(&adresse16,sizeof(_int16),1,txt_f);
			adresse=adresse16;
		} else
			fread(&adresse,sizeof(_int32),1,txt_f);
		adresses_nb=adresse/Txt_Type_Ptr-1;
		// Inscription du nombre de pointeurs
		fprintf(out_f,"%05d",adresses_nb);
		// Placement au niveau du texte
		fseek(txt_f,adresse,SEEK_SET);
		// Lecture du texte
		for(t=0;t<adresses_nb;t++) {
			// Inscription du pointeur
			Txt_Pointeur(t,out_f);
			// Extraction du texte
			while(Tbl_Lecture(txt_f,out_f)!=R_PTR);
		}
		Txt_Pointeur(t,out_f);
		// Fermeture des fichiers
		fclose(out_f);
		fclose(txt_f);
	}

	Main_OK();
}

/*------------------------------------------------------------------
  Test sur une ligne pour déceler un manque de pointeur
--------------------------------------------------------------------
 <- ligne : ligne de texte à tester
------------------------------------------------------------------*/
int Txt_Test_Ligne (char *ligne)
{
	unsigned int c;
	int ptr=ER;

	// Teste les premiers caratères de la ligne
	// par exemple ----- pour vérifier si on n'a
	// pas oublié un pointeur au dessus
	for(c=0;c<strlen(ligne) && c<TXT_PTR_TEST && ptr==ER;c++)
		if (ligne[c]!=TXT_PTR_CAR)
			ptr=OK;

	return(ptr);
}

/*------------------------------------------------------------------
  Réinsertion des textes d'un fichier
--------------------------------------------------------------------
 <- fich : dossier|fichier (sans extension pour dossier)
------------------------------------------------------------------*/
void Txt_Reinsertion (char *fich)
{
	// Dossier/fichiers
	char* dir;
	char* fichier;
	// Fichier de textes à modifier
	FILE *txt_f;
	char txt_nom[TXT_NOM_MAX];
	char *txt_nom2;
	char txt_nom_complet[TXT_NOM_MAX];
	// Fichiers d'entrée
	FILE *in_f;
	// Nom du dossier
	char dossier[TXT_NOM_MAX];
	// Pointeurs sur le texte
	unsigned _int32 adresses[TXT_BLOCS_NB];
	_int16 adresse16;
	int adresses_nb=-1;
	// Index des fichiers et blocs
	int t;
	// Ligne de texte lue
	char ligne[TXT_LIGNE_MAX];
	// Position dans le fichier texte
	unsigned int pos;

	Main_Message_S("Reinsertion des textes de %s... ",fich,OK);

	// Décomposition dossier/fichier
	dir=strtok(fich,SEPARATEUR);
	if (dir[0]==NEUTRE)
		dir[0]=0;
	fichier=strtok(NULL,SEPARATEUR);

	// Recherche du fichier de textes de sortie
	sprintf(dossier,"%s%s",DIR_FICH_OUT,dir);
	sprintf(txt_nom,"%04d",atoi(fichier));
	Fichier_Cherche(dossier,txt_nom,EXT_TXT,&txt_nom2);
	sprintf(txt_nom_complet,"%s%s",dossier,txt_nom2);
	in_f=fopen(txt_nom_complet,"rb");

	// Fichier correctement copié ?
	if (in_f==NULL)
		Main_Message_S("Impossible de reinserer le fichier.\n","",ER);
	else {
		// Chargement des paramètres de décompression
		Txt_Infos(dir,txt_nom,TBL_OUT);
		// Ouverture du texte extrait
		strcpy(&txt_nom_complet[strlen(txt_nom_complet)-3],EXT_TBT);
		txt_f=fopen(txt_nom_complet,"wb");
		// Lecture du nombre de pointeurs
		fgets(ligne,TXT_LIGNE_MAX,in_f);
		sscanf(ligne,"%05d",&adresses_nb);
		// Placement dans le fichier des textes
		fseek(txt_f,(adresses_nb+1)*Txt_Type_Ptr,SEEK_SET);
		// Réinsertion des textes
		for(t=0;Main_Test()==OK && t<adresses_nb;t++) {
			// Lecture le la ligne d'information du pointeur
			fgets(ligne,TXT_LIGNE_MAX,in_f);
			// Récupération de l'adresse
			adresses[t]=ftell(txt_f);
			if (t>0) // Pour le retour (pas bien !!!)
				adresses[t]--;
			fseek(txt_f,adresses[t],SEEK_SET);
			// Lecture du texte extrait jusqu'à un pointeur
			pos=ftell(in_f);
			do {
				fseek(in_f,pos,SEEK_SET);
				fgets(ligne,TXT_LIGNE_MAX,in_f);
				if (Txt_Test_Ligne(ligne)==ER)
					Main_Message_D("Manque un pointeur en %d.\n",t,ER);
				pos=ftell(in_f);
				// Traitement de la ligne
			} while (Main_Test()==OK && Tbl_Ecriture(ligne,txt_f)!=R_PTR);
		}
		//adresses[0]--; // Pas bien (bis)
		adresses[t]=ftell(txt_f);
		// Fermeture du texte extrait
		fclose(in_f);
		// Réinsertion des adresses
		fseek(txt_f,0,SEEK_SET);
		for(t=0;t<=adresses_nb;t++)
			if (Txt_Type_Ptr==2) {
				adresse16=(_int16)adresses[t];
				fwrite(&adresse16,sizeof(_int16),1,txt_f);
			} else
				fwrite(&adresses[t],sizeof(_int32),1,txt_f);
		// Fermeture du fichier des textes
		fclose(txt_f);
	}

	Main_OK();
}